/* eslint-disable vue/no-setup-props-destructure */
import type { mapViewPropsType, mapViewStateType } from './typings'
import { defineComponent, reactive, watch, onBeforeUnmount } from 'vue'
import { ElLoading } from 'element-plus'
import { isPlainObject } from 'lodash'
import useVuexGetters from '~/hooks/useVuexGetters'
import useAMap from '~/hooks/useAMap'

export default defineComponent({
  name: 'MapView',
  props: ['id', 'clickon', 'marker'],
  emits: ['selectAddressList', 'setAddressInfo', 'clickMarker'],
  setup(props: mapViewPropsType, { emit, expose }) {
    const { id = 'container' } = props
    const state = reactive<mapViewStateType>({
      currentMarker: undefined,
      currentMarkerShadow: undefined
    })
    // 获取租户设置的坐标
    const userState = useVuexGetters('user', ['userAddressInfo'])
    const loading = ElLoading.service({
      target: `#${id}`,
      // lock: true,
      text: '加载中'
    })
    const [mapRef, aMapRef, amapIconRef] = useAMap(
      id,
      {
        center: [userState.userAddressInfo.value.lon, userState.userAddressInfo.value.lat],
        zoom: 11
      },
      initAMap
    )

    // 获取当前标记点经纬度下的地址列表
    const handleCurrentMarkerAddressList = (lng: number, lat: number) => {
      const geocoder = new aMapRef.value.Geocoder({
        radius: 100 // 范围，默认：500
      })
      geocoder.getAddress(
        [lng, lat],
        (status: string, result: { regeocode: { formattedAddress: string } }) => {
          if (status === 'complete' && result.regeocode) {
            // emit('setAddressInfo', {
            //   address: result.regeocode.formattedAddress,
            //   addressCoordinates: [lng, lat]
            // })
            emit('setAddressInfo', result.regeocode.formattedAddress, [lng, lat])
          }
          // else {
          //   ElMessage.error('查询地址失败')
          // }
        }
      )
      // aMapRef.value.plugin(['AMap.PlaceSearch'], () => {
      //   const geocoder = new aMapRef.value.PlaceSearch({
      //     pageSize: 10, // 每页结果数,默认10
      //     pageIndex: 1 // 请求页码，默认1
      //   })
      //   geocoder.searchNearBy(
      //     '',
      //     new aMapRef.value.LngLat(lng, lat),
      //     50,
      //     (status: string, result: { info: string; poiList: { pois: aliMapAddressTypes[] } }) => {
      //       if (status === 'complete' && result.info === 'OK') {
      //         emit('selectAddressList', result?.poiList?.pois || [])
      //       } else {
      //         emit('selectAddressList', [])
      //       }
      //     }
      //   )
      // })
    }

    // 添加marker点击事件 将储存的值发送给父元素
    const handleClickMarkerCallback = (e: { target: mapViewStateType['currentMarker'] }) => {
      emit('clickMarker', e?.target!?.getExtData?.())
    }

    // 拖拽时移动标记点实时更新标记点的阴影位置
    const handleDraggingMarkerCallback = () => {
      const markerPosition = state.currentMarker!.getPosition()
      state.currentMarkerShadow!.setCenter([markerPosition?.lng, markerPosition?.lat])
    }

    // 拖拽结束后移动标记点并查询地址
    const handleDragMarkerCallback = () => {
      const markerPosition = state.currentMarker!.getPosition()
      mapRef.value.setCenter([markerPosition.lng, markerPosition.lat], true)
      state.currentMarkerShadow!.setCenter([markerPosition.lng, markerPosition.lat])
      handleCurrentMarkerAddressList(markerPosition.lng, markerPosition.lat)
    }

    // 清除标记点
    const handleClearAMapMarker = () => {
      mapRef.value.clearMap()
      state.currentMarker = undefined
      state.currentMarkerShadow = undefined
    }

    // 添加标点
    const handleAddAMapMarker = (
      lng: number,
      lat: number,
      item?: mapViewStateType['currentMarker']
    ) => {
      if (state.currentMarker) handleClearAMapMarker()
      const marker = new aMapRef.value.Marker({
        icon: amapIconRef.value,
        position: [lng, lat],
        offset: [-12, -22],
        // zooms: [2, 18],
        extData: item || {},
        draggable: true
      })
      const markerShadow = new aMapRef.value.CircleMarker({
        center: [lng, lat],
        radius: 50,
        // zooms: [2, 18],
        fillColor: '#FFBBBB',
        fillOpacity: 0.3,
        strokeOpacity: 0
      })
      // .setExtDate(item || {})
      state.currentMarker = marker
      state.currentMarkerShadow = markerShadow
      mapRef.value.add(marker)
      mapRef.value.add(markerShadow)
      mapRef.value.setFitView()
      marker.on('click', handleClickMarkerCallback)
      marker.on('dragging', handleDraggingMarkerCallback)
      marker.on('dragend', handleDragMarkerCallback)
      handleCurrentMarkerAddressList(lng, lat)
    }

    // 单击地图事件回调
    const handleClickAMapCallback = (mapsEvent: { lnglat: { lng: number; lat: number } }) => {
      const {
        lnglat: { lng, lat }
      } = mapsEvent
      if (state.currentMarker) return
      handleAddAMapMarker(lng, lat)
    }

    // 根据props.marker来设置坐标点回调
    const handleSetMarkerByPropsMarkers = () => {
      if (props.marker && aMapRef.value) {
        const timer = setTimeout(() => {
          if (isPlainObject(props.marker)) {
            const item = props.marker
            handleAddAMapMarker(
              (item as Record<string, any>)?.lng,
              (item as Record<string, any>)?.lat,
              item as any
            )
          }
          clearTimeout(timer)
        }, 0)
      }
    }

    // 初始化map事件
    function initAMap() {
      loading.close()
      const { clickon = false } = props
      if (clickon) mapRef.value.on('click', handleClickAMapCallback)
      if (props.marker && aMapRef.value) handleSetMarkerByPropsMarkers()
    }

    watch(
      () => props.marker,
      () => {
        if (state.currentMarker && props.marker) {
          mapRef.value.setCenter([props.marker!.lng, props.marker!.lat])
          state.currentMarker.setPosition([props.marker!.lng, props.marker!.lat])
          state.currentMarkerShadow!.setCenter([props.marker!.lng, props.marker!.lat])
          handleCurrentMarkerAddressList(props.marker!.lng, props.marker!.lat)
        } else if (!state.currentMarker && props.marker && mapRef.value) {
          handleAddAMapMarker(props.marker!.lng, props.marker!.lat, props.marker)
        }
      }
      // { deep: true }
    )

    onBeforeUnmount(async () => {
      await mapRef.value.destroy()
    })

    expose({
      mapRef,
      aMapRef,
      setMarkersByPropsMarkers: handleSetMarkerByPropsMarkers,
      clearCurrentMarker: handleClearAMapMarker,
      mapState: state
    })
    return () => <section id={id}></section>
  }
})
